package br.com.unirio.formula1.servico;

import java.util.Set;

import br.com.unirio.formula1.modelo.Campeonato;
import br.com.unirio.formula1.modelo.Equipe;
import br.com.unirio.formula1.modelo.Piloto;
import br.com.unirio.formula1.modelo.Resultado;
import br.com.unirio.formula1.util.exception.ExcecaoDeServico;

/**
 * 
 * Classe responsavel por gerar, a partir de um campeonato , o produto final da aplicacao : As classificacoes gerais de
 * Piloto ({@link ClassificacaoPiloto}) e de Equipe ({@link ClassificacaoEquipe}).
 * 
 * 
 * @author Victor
 * 
 */
public class GeradorDeClassificacao
{

    public ClassificacaoEquipe gerarClassificacaoEquipe(Campeonato campeonato) throws ExcecaoDeServico
    {

	validarDadosResultados(campeonato);
	ClassificacaoEquipe classificacao = new ClassificacaoEquipe();
	int quantidadePilotos = campeonato.getPilotos().size();

	for (Equipe equipe : campeonato.getEquipes())
	{
	    ColocacaoEquipe colocacao = new ColocacaoEquipe(equipe, quantidadePilotos);
	    adicionarResultadosNoColocado(colocacao, campeonato.getResultados());
	    classificacao.addColocacao(colocacao);

	}

	classificacao.ordenar();
	classificacao.atribuirPosicoes();

	return classificacao;
    }

    public ClassificacaoPiloto gerarClassificacaoPiloto(Campeonato campeonato) throws ExcecaoDeServico
    {

	validarDadosResultados(campeonato);
	ClassificacaoPiloto classificacao = new ClassificacaoPiloto();
	int quantidadePilotos = campeonato.getPilotos().size();

	for (Piloto piloto : campeonato.getPilotos())
	{
	    ColocacaoPiloto colocacao = new ColocacaoPiloto(piloto, quantidadePilotos);
	    adicionarResultadosNoColocado(colocacao, campeonato.getResultados());
	    classificacao.addColocacao(colocacao);

	}

	classificacao.ordenar();
	classificacao.atribuirPosicoes();

	return classificacao;
    }

    private void adicionarResultadosNoColocado(ColocacaoPiloto colocacao, Set<Resultado> resultados)
    {
	for (Resultado resultado : resultados)
	{
	    colocacao.addResultado(resultado);
	}

    }

    private void adicionarResultadosNoColocado(ColocacaoEquipe colocacao, Set<Resultado> resultados)
    {
	for (Resultado resultado : resultados)
	{
	    colocacao.addResultado(resultado);
	}

    }

    /**
     * Metodo responsavel por checar se existe algum resultado cadastrado para gerar a classificacao
     * 
     * 
     * @param campeonato
     * @throws ExcecaoDeServico
     */
    private void validarDadosResultados(Campeonato campeonato) throws ExcecaoDeServico
    {
	if (campeonato.getResultados().isEmpty())
	    throw new ExcecaoDeServico("GeradorDeClassificacao.resultadosVazios");

    }

}
